package com.haierp.controller;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentMap;

import javax.imageio.ImageIO;

import com.google.common.collect.Maps;
import com.haierp.model.sale.OuterOrder;
import com.haierp.util.yitao.YtDimensionCodeUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jetty.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.haierp.enums.OrderStatus;
import com.haierp.enums.StockUpStatus;
import com.haierp.exception.ErpCommonException;
import com.haierp.exception.InventoryException;
import com.haierp.mapper.ErpOrderMapper;
import com.haierp.model.ErpOrder;
import com.haierp.model.Seller;
import com.haierp.model.ShippingOrder;
import com.haierp.service.IErpOrderService;
import com.haierp.service.IInventoryService;
import com.haierp.service.ISellerService;
import com.haierp.service.IShippingOrderService;
import com.haierp.util.AnalysisExcelUtil;
import com.haierp.util.BizResult;
import com.haierp.util.DateUtil;
import com.haierp.util.JsonPageResult;
import com.haierp.util.JsonResult;
import com.haierp.util.ExcelTool.ExcelHelper;
import com.haierp.vo.ErpOrderQueryVO;
import com.haierp.vo.json.PicModel;
import com.wangzhixuan.commons.base.BaseController;
import com.wangzhixuan.commons.shiro.ShiroUser;
import com.wangzhixuan.commons.utils.HaiJsonUtils;

/**
 * @author liuhui
 */
@Controller
@RequestMapping("/erpOrder")
public class ErpOrderController extends BaseController {

    @Autowired
    private IErpOrderService erpOrderService;
    @Autowired
    private IInventoryService inventoryService;
    @Autowired
    private IShippingOrderService shippingOrderService;
    @Autowired
    private ISellerService sellerService;
    @Autowired
    private ErpOrderMapper erpOrderMapper;

    @RequestMapping("/query")
    @ResponseBody
    public Object query(ErpOrderQueryVO erpOrderQueryVO) {
        JsonPageResult<List<ErpOrder>> result = new JsonPageResult<>();
        if (erpOrderQueryVO.getEndGmtCreate() != null) {
            String endGmtCreateStr = DateUtil.ymdFormat(erpOrderQueryVO.getEndGmtCreate());
            Date endGmtCreate = DateUtil.parseDate(endGmtCreateStr + " 23:59:59");
            erpOrderQueryVO.setEndGmtCreate(endGmtCreate);
        }
        if (erpOrderQueryVO.getPkgEndGmtCreate() != null) {
            String pkgEndGmtCreateStr = DateUtil.ymdFormat(erpOrderQueryVO.getPkgEndGmtCreate());
            Date pkgEndGmtCreate = DateUtil.parseDate(pkgEndGmtCreateStr + " 23:59:59");
            erpOrderQueryVO.setPkgEndGmtCreate(pkgEndGmtCreate);
        }
        //如果是代理
        ShiroUser shiroUser = this.getShiroUser();
        Set<String> roles = shiroUser.getRoles();
        if (roles.contains("irhdaili")) {
            String[] logingNameArr = shiroUser.getLoginName().split("_");
            if (logingNameArr.length < 2 || StringUtils.isBlank(logingNameArr[1])) {
                throw new ErpCommonException("用户权限异常");
            }
            erpOrderQueryVO.setSalesId(Integer.parseInt(logingNameArr[1]));
            Seller seller = sellerService.selectById(erpOrderQueryVO.getSalesId());
            if (seller.getOpenId() != null) {
                erpOrderQueryVO.setOpenId(seller.getOpenId());
            }
        }
        if (StringUtils.isNotBlank(erpOrderQueryVO.getSalesName())) {
            String s = erpOrderQueryVO.getSalesName().replace("&quot;", "\"");
            String ss = "[" + s + "]";
            List<Long> sellerIdList = HaiJsonUtils.toBean(ss, new TypeReference<List<Long>>() {
            });
            erpOrderQueryVO.setSellersId(sellerIdList);
        }
        result = erpOrderService.queryErpOrders(erpOrderQueryVO);

        if (!roles.contains("telephone")) {
            List<ErpOrder> erpOrderList = result.getData();
            erpOrderList.forEach(erpOrder -> {
                String tel = erpOrder.getTelephone();
                if (StringUtil.isNotBlank(tel)) {
                    erpOrder.setTelephone(tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
                }
            });
        }

        if (roles.contains("irhdaili")) {
            result.setAgentRoler(true);
        }
        if (roles.contains("noexport")) {
            result.setNoEexportRoler(true);
        }
        if (roles.contains("yunying") || roles.contains("admin")) {
            result.setYunyinger(true);
        }
        if (shiroUser.getCompanyId() == 2 || shiroUser.getCompanyId() == 3) {
            result.setXhsButton(true);
        }
        result.setSuccess(true);
        return result;
    }

    @RequestMapping("/queryById")
    @ResponseBody
    public Object queryById(Long id) {
        JsonResult<ErpOrder> result = new JsonResult<>();
        ErpOrder erpOrder = erpOrderService.selectById(id);

        ShiroUser shiroUser = this.getShiroUser();
        Set<String> roles = shiroUser.getRoles();
        if (!roles.contains("telephone")) {
            String tel = erpOrder.getTelephone();
            if (StringUtil.isNotBlank(tel)) {
                erpOrder.setTelephone(tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
            }
        }

        result.buildIsSuccess(true).setData(erpOrder);
        return result;
    }

    @RequestMapping("/update")
    @ResponseBody
    public Object update(ErpOrder erpOrder) {
        JsonResult<ErpOrder> result = new JsonResult<>();
        ShiroUser shiroUser = this.getShiroUser();
        erpOrder.setUserModify(shiroUser.getLoginName());
        erpOrder.setGmtModify(new Date());
        erpOrder.setQuantity(null);//不能修改销售数量，需要在主订单哪里修改数量
        erpOrderService.updateSelectiveById(erpOrder);
        result.setSuccess(true);
        return result;
    }


    /**
     * 子订单批量关闭
     *
     * @param orderIds
     * @return
     */
    @RequestMapping("/close")
    @ResponseBody
    public Object close(String orderIds, String closeReason) {
        List<String> errorMsg = Lists.newArrayList();
        if (StringUtils.isNotBlank(orderIds)) {
            String s = orderIds.replace("&quot;", "\"");
            List<Long> orderIdList = HaiJsonUtils.toBean(s, new TypeReference<List<Long>>() {
            });
            Set<Long> mainIds = Sets.newHashSet();
            int i = 0;
            for (Long orderId : orderIdList) {
                i++;
                ErpOrder erpOrder = erpOrderService.selectById(orderId);
                if (erpOrder == null) {
                    errorMsg.add("第" + i + "条订单数据有误,");
                } else {
                    if (erpOrder.getStatus() == OrderStatus.INIT.getCode()) {
                        try {
                            if (StringUtil.isNotBlank(closeReason)) {
                                erpOrder.setCloseReason(closeReason);
                            }
                            erpOrderService.closeErpOrder(erpOrder);
                            mainIds.add(erpOrder.getOuterOrderId());
                        } catch (Exception e) {
                            errorMsg.add("第" + i + "条订单关闭失败,");
                            this.logger.error(e);
                        }
                    } else {
                        errorMsg.add("第" + i + "条订单状态有误,");
                    }
                }

            }
            //更新主订单发货状态
            if (CollectionUtils.isNotEmpty(mainIds)) {
                shippingOrderService.updateOuterstatus(mainIds);
            }
            String rmsg = "";
            if (CollectionUtils.isNotEmpty(errorMsg)) {
                for (String a : errorMsg) {
                    rmsg += a;
                }
                return JsonResult.buildFailed(rmsg);
            } else {
                return JsonResult.buildSuccess(null);
            }
        } else {
            return JsonResult.buildFailed("参数错误");
        }
    }


    @RequestMapping("/splitErpOrder")
    @ResponseBody
    public Object splitErpOrder(Long orderId, Integer splitCount) {
        if (orderId == null) {
            return JsonResult.buildFailed("订单ID错误");
        }
        if (splitCount == null || splitCount <= 0) {
            return JsonResult.buildFailed("数量错误");
        }
        ErpOrder erpOrder = erpOrderService.selectById(orderId);
        if (erpOrder == null) {
            return JsonResult.buildFailed("未找到订单");
        } else {
            if (erpOrder.getQuantity() == 1) {
                return JsonResult.buildFailed("一个商品不能拆分");
            }
            if (erpOrder.getStatus() == OrderStatus.INIT.getCode()) {
                try {
                    if (splitCount >= erpOrder.getQuantity()) {
                        return JsonResult.buildFailed("拆单数量不能超过订单数量");
                    }
                    erpOrderService.splitErpOrder(erpOrder, splitCount);
                } catch (InventoryException ie) {
                    return JsonResult.buildFailed(ie.getMessage());
                } catch (Exception ie) {
                    this.logger.error(ie);
                    return JsonResult.buildFailed("未知异常");
                }
            } else {
                return JsonResult.buildFailed("子订单状态错误");
            }
        }
        return JsonResult.buildSuccess(null);
    }

    /**
     * 释放库存
     *
     * @param orderId
     * @return
     */
    @RequestMapping("/releaseInventory")
    @ResponseBody
    public Object releaseInventory(Long id) {
        if (id == null) {
            return JsonResult.buildFailed("订单ID错误");
        }
        ErpOrder erpOrder = erpOrderService.selectById(id);
        if (erpOrder == null) {
            return JsonResult.buildFailed("未找到订单");
        } else {
            //订单状态校验
            if (erpOrder.getStatus() == OrderStatus.INIT.getCode() && erpOrder.getStockStatus() != StockUpStatus.RELEASED.getCode() && erpOrder.getStockStatus() != StockUpStatus.INIT.getCode()) {
                try {
                    inventoryService.releaseInventory(erpOrder);
                } catch (InventoryException e) {
                    logger.error("orderId:" + id + e.getMessage() + e);
                    return JsonResult.buildFailed("操作失败，位置错误");
                }
            } else {
                return JsonResult.buildFailed("订单状态错误");
            }
        }
        return JsonResult.buildSuccess(null);
    }

    /**
     * 指定订单备货
     *
     * @param orderId
     * @return
     */
    @RequestMapping("/lockErpOrder")
    @ResponseBody
    public Object lockErpOrder(Long id) {
        if (id == null) {
            return JsonResult.buildFailed("订单ID错误");
        }
        ErpOrder erpOrder = erpOrderService.selectById(id);
        if (erpOrder == null) {
            return JsonResult.buildFailed("未找到订单");
        } else {
            try {
                BizResult bizResult = erpOrderService.lockErpOrder(erpOrder);
                if (!bizResult.isSuccess()) {
                    return JsonResult.buildFailed(bizResult.getMsg());
                }
            } catch (InventoryException e) {
                logger.info("orderId:" + id + e);
            }
        }
        return JsonResult.buildSuccess(null);
    }

    /**
     * 子订单批量重新分配库存
     *
     * @param orderIds
     * @return
     */
    @RequestMapping("/replayAssign")
    @ResponseBody
    public Object replayAssign(String orderIds) {
        List<String> errorMsg = Lists.newArrayList();
        if (StringUtils.isNotBlank(orderIds)) {
            String s = orderIds.replace("&quot;", "\"");
            List<Long> orderIdList = HaiJsonUtils.toBean(s, new TypeReference<List<Long>>() {
            });
            List<ErpOrder> erpOrders = Lists.newArrayList();
            int i = 0;
            String skuCode = null;
            List<String> idList = Lists.newArrayList();
            for (Long orderId : orderIdList) {
                i++;
                ErpOrder erpOrder = erpOrderService.selectById(orderId);
                if (erpOrder == null) {
                    errorMsg.add("第" + i + "条订单数据有误,");
                } else {
                    if (erpOrder.getSalesId() != null && erpOrder.getSalesId().equals(46L)) {
                        idList.add(erpOrder.getId().toString());
                    }
                    erpOrders.add(erpOrder);
                    if (erpOrder.getStatus() == OrderStatus.INIT.getCode()) {
                        if (skuCode == null) {
                            skuCode = erpOrder.getSkuCode();
                        } else {
                            if (!skuCode.equals(erpOrder.getSkuCode())) {
                                errorMsg.add("第" + i + "条订单有不同的SKU,");
                            }
                        }
                    } else {
                        errorMsg.add("第" + i + "条订单状态有误,");
                    }
                }
            }
            //提交订单集合
            String path = "/yitao/api/order/start/push";
            if (idList != null && idList.size() > 0) {
                Map<String, Object> map = Maps.newConcurrentMap();
                map.put("orderIdList", idList);
                try {
                    YtDimensionCodeUtil.yitaoHttpPostRequest(path, map, "POST");
                } catch (Exception e) {
                    logger.info("orderIds:" + idList + e);
                    e.printStackTrace();
                    return JsonResult.buildFailed("参数错误");
                }
            }
            StringBuilder rmsg = new StringBuilder();
            if (CollectionUtils.isNotEmpty(errorMsg)) {
                for (String a : errorMsg) {
                    rmsg.append(a);
                }
                return JsonResult.buildFailed(rmsg.toString());
            } else {
                if (erpOrders.size() > 1) {
                    erpOrders.sort((a, b) -> {
                        if (a.getId() > b.getId()) {
                            return 1;
                        } else {
                            return -1;
                        }
                    });
                }
                //批量释放库存
                erpOrders.forEach(order -> {
                    try {
                        if (order.getStockStatus() != StockUpStatus.INIT.getCode() && order.getStockStatus() != StockUpStatus.RELEASED.getCode()) {
                            inventoryService.releaseInventory(order);
                        }
                    } catch (Exception e) {
                        logger.info(e);
                    }
                });
                //批量重新分配库存
                erpOrders.forEach(order -> {
                    try {
                        erpOrderService.lockErpOrder(order);
                    } catch (Exception e) {
                        logger.info(e);
                    }
                });
                return JsonResult.buildSuccess(null);
            }

        } else {
            return JsonResult.buildFailed("参数错误");
        }
    }

    /**
     * 导出excel
     *
     * @param id
     */
    @RequestMapping("/erpOrderExport")
    public ResponseEntity<byte[]> erpOrderExport(ErpOrderQueryVO erpOrderQueryVO) throws Exception {
        List<List<Object>> rowDatas = new ArrayList<>();
        if (erpOrderQueryVO.getStartGmtCreate() != null && erpOrderQueryVO.getEndGmtCreate() != null) {
            //throw new ErpCommonException("必须选择创建时间段");
            String startGmtCreateStr = DateUtil.ymdFormat(erpOrderQueryVO.getStartGmtCreate());
            Date startGmtCreate = DateUtil.parseDate(startGmtCreateStr + " 00:00:00");
            erpOrderQueryVO.setStartGmtCreate(startGmtCreate);
            String endGmtCreateStr = DateUtil.ymdFormat(erpOrderQueryVO.getEndGmtCreate());
            Date endGmtCreate = DateUtil.parseDate(endGmtCreateStr + " 23:59:59");
            erpOrderQueryVO.setEndGmtCreate(endGmtCreate);
        }
        if (erpOrderQueryVO.getPkgStartGmtCreate() != null && erpOrderQueryVO.getPkgEndGmtCreate() != null) {
            String pkgStartGmtCreateStr = DateUtil.ymdFormat(erpOrderQueryVO.getPkgStartGmtCreate());
            Date pkgStartGmtCreate = DateUtil.parseDate(pkgStartGmtCreateStr + " 00:00:00");
            erpOrderQueryVO.setPkgStartGmtCreate(pkgStartGmtCreate);
            String pkgEndGmtCreateStr = DateUtil.ymdFormat(erpOrderQueryVO.getPkgEndGmtCreate());
            Date pkgEndGmtCreate = DateUtil.parseDate(pkgEndGmtCreateStr + " 23:59:59");
            erpOrderQueryVO.setPkgEndGmtCreate(pkgEndGmtCreate);
        }
        if (erpOrderQueryVO.getPkgStartGmtCreate() == null && erpOrderQueryVO.getStartGmtCreate() == null) {
            throw new ErpCommonException("必须选择创建时间段");
        }
        if (StringUtils.isNotBlank(erpOrderQueryVO.getSalesName())) {
            String s = erpOrderQueryVO.getSalesName().replace("&quot;", "\"");
            String ss = "[" + s + "]";
            List<Long> sellerIdList = HaiJsonUtils.toBean(ss, new TypeReference<List<Long>>() {
            });
            erpOrderQueryVO.setSellersId(sellerIdList);
        }

        ShiroUser shiroUser = this.getShiroUser();
        Set<String> roles = shiroUser.getRoles();

        List<ErpOrder> erpOrderList = erpOrderService.queryErpOrderForExcel(erpOrderQueryVO);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (erpOrderList != null) {
            for (ErpOrder erpOrder : erpOrderList) {
                List<Object> list = new ArrayList<>();
                //sku图片
                String skuPic = erpOrder.getSkuPic();
                if (StringUtil.isNotBlank(skuPic)) {
                    PicModel pm = HaiJsonUtils.toBean(skuPic, PicModel.class);
                    String imgSrc = pm.getPicList().get(0).getUrl();
                    String imgType = imgSrc.substring(imgSrc.lastIndexOf(".") + 1).toUpperCase();
                    if (imgSrc.contains("aliyuncs.com")) {
                        imgSrc += "?x-oss-process=image/resize,m_lfit,h_100,w_100";
                    } else {
                        imgSrc = imgSrc.replaceAll("Resource", "Thumbnail");
                    }
                    //System.out.println(imgSrc);
                    URL url = new URL(imgSrc);
                    BufferedImage image = ImageIO.read(url);
                    ByteArrayOutputStream output = new ByteArrayOutputStream();
                    ImageIO.write(image, imgType, output);
                    output.flush();
                    list.add(output.toByteArray());
                    output.close();
                } else {
                    list.add(null);
                }

                list.add(erpOrder.getItemName());    //商品名称
                list.add(erpOrder.getColor());        //颜色
                list.add(erpOrder.getScale());        //尺码
                list.add(erpOrder.getOrderNo());    //主订单号
                list.add(erpOrder.getErpNo());        //子订单号
                list.add(erpOrder.getSkuCode());    //商品条码
                list.add(erpOrder.getSalesName());    //订单来源
                list.add(erpOrder.getQuantity());    //销售数量
                list.add(erpOrder.getSalePrice());    //销售价格
                list.add(erpOrder.getQuantity() * erpOrder.getSalePrice());               //销售总价
                list.add(OrderStatus.of(erpOrder.getStatus()).getDescription());        //订单状态
                list.add(StockUpStatus.of(erpOrder.getStockStatus()).getDescription());    //备货状态
                list.add(formatter.format(erpOrder.getOrderTime()));                    //创建时间
                if (erpOrder.getPkgGmtCreate() == null) {
                    list.add("");
                } else {
                    list.add(formatter.format(erpOrder.getPkgGmtCreate()));                //发货时间
                }
                list.add(erpOrder.getTargetNo());    //外部订单号
                list.add(erpOrder.getNickName());    //小程序用户
                list.add(erpOrder.getReceiver());    //收件人
                list.add(erpOrder.getIdCard());    //收件人身份证
                //收件人电话
                if (!roles.contains("telephone")) {
                    String tel = erpOrder.getTelephone();
                    if (StringUtil.isNotBlank(tel)) {
                        list.add(tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
                    }
                } else {
                    list.add(erpOrder.getTelephone());
                }
                list.add(erpOrder.getReceiverState() + erpOrder.getReceiverCity() + erpOrder.getReceiverDistrict() + "\r\n" + erpOrder.getAddressDetail());        //地址
                list.add(erpOrder.getLogisticCompany());         //物流公司
                list.add(erpOrder.getShippingNo());                //包裹号
                list.add(erpOrder.getLogisticNo());                //物流单号
                list.add(erpOrder.getRemark());                //备注


                rowDatas.add(list);
            }
        }
        ExcelHelper excelHelper = new ExcelHelper();
        String[] columnTitles = new String[]{"商品图片", "商品名称", "颜色", "尺码", "主订单号", "子订单号", "SKU代码", "订单来源", "销售数量", "商品价格", "销售总价", "订单状态", "备货状态", "创建时间", "发货时间", "外部订单号", "小程序客户", "收件人", "收件人身份证", "手机", "地址", "物流公司", "包裹号", "物流单号", "备注"};
        Integer[] columnWidth = new Integer[]{10, 30, 10, 10, 20, 20, 20, 12, 10, 10, 10, 10, 10, 12, 12, 20, 20, 15, 16, 15, 30, 15, 20, 20, 20};
        excelHelper.setErpOrderToSheet("Erp Order", columnTitles, rowDatas, columnWidth);
        //excelHelper.writeToFile("/Users/liuyang/Work/test.xls");

        ResponseEntity<byte[]> filebyte = null;
        ByteArrayOutputStream out = excelHelper.writeToByteArrayOutputStream();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        String fileName = "子订单(" + DateUtil.formatDate(erpOrderQueryVO.getStartGmtCreate(), "yyyyMMdd") + ").xlsx";
        headers.setContentDispositionFormData("attachment", new String(fileName.getBytes("utf-8"), "ISO8859-1"));

        filebyte = new ResponseEntity<byte[]>(out.toByteArray(), headers, HttpStatus.OK);
        out.close();
        excelHelper.close();
        return filebyte;
    }

    /**
     * 身份证填入子订单
     */
    @RequestMapping("/importIdCard")
    @ResponseBody
    public Object importIdCard(String fileUrl) {
        JsonResult<Object> result = new JsonResult<>();
        List<List<Object>> allRows = AnalysisExcelUtil.analysisExcel(fileUrl);
        Map<String, String> tartID = new HashMap<String, String>();
        for (int i = 0; i < allRows.size(); i++) {
            List<Object> rowDataTemp = allRows.get(i);
            tartID.put(rowDataTemp.get(0).toString(), rowDataTemp.get(26).toString());
        }
        for (Map.Entry<String, String> entry : tartID.entrySet()) {
            erpOrderService.updateErpIdCard(entry.getKey(), entry.getValue());
        }
        return result.buildIsSuccess(true);
    }


    /**
     * 结算标记
     */
    @RequestMapping("/remarkBalanceOrder")
    @ResponseBody
    public Object remarkBalanceOrder(String fileUrl, String remark) throws Exception {
        JsonResult<Object> result = new JsonResult<>();
        List<List<Object>> allRows = AnalysisExcelUtil.analysisExcel(fileUrl);

        List<ErpOrder> erpOrderList = new ArrayList<ErpOrder>();
        for (int i = 0; i < allRows.size(); i++) {
            List<Object> rowDataTemp = allRows.get(i);
            ErpOrder erpOrder = new ErpOrder();
            if (StringUtil.isBlank(rowDataTemp.get(0).toString())) {
                continue;
            }
            erpOrder.setErpNo(rowDataTemp.get(0).toString());
            erpOrder.setPayStatus(1);
            erpOrder.setBalanceRemark(remark);
            erpOrderList.add(erpOrder);
        }
        if (erpOrderList.size() > 0) {
            erpOrderMapper.balanceOrder(erpOrderList);
        }
        return result.buildIsSuccess(true);
    }

}
